package com.itheima.travel.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.log4j2.Log4j2Impl;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * @Description：声明mybatis的配置
 */
@Configuration
//读取外部配置文件
@PropertySource(value = "classpath:db.properties")
// 代替MapperScannerConfigurer进行包扫描
// mapper: 存放代码生成器生成的单表增删改查
// mapperExt: 存放我们自己编写的多表增删改查
@MapperScan(
        basePackages =
                {
                        "com.itheima.travel.mapper",
                        "com.itheima.travel.mapperExt"
                },
        sqlSessionFactoryRef = "sqlSessionFactoryBean")
public class MybatisConfig {

    @Value("${dataSource.driverClassName}")
    private String driverClassName;

    @Value("${dataSource.url}")
    private String url;

    @Value("${dataSource.username}")
    private String username;

    @Value("${dataSource.password}")
    private String password;
    // 雪花算法使用的机房号
    @Value("${seq.workerId}")
    private String workerId;

    // 雪花算法使用的机器号
    @Value("${seq.datacenterId}")
    private String datacenterId;

    /**
     * @Description 数据源配置
     * 细节：默认不指定名称使用当前方法名为bean的名称
     */
    @Bean("druidDataSource")
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * @Description 配置事务管理器
     * 细节：名称必须是：transactionManager，如果更换需要在使用时指定
     */
    @Bean("transactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("druidDataSource") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * @Description 配置会话管理器
     */
    @Bean("sqlSessionFactoryBean")
    public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("druidDataSource") DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //指定数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        //指定对应的别名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.itheima.travel.pojo");
        //指定高级配置：驼峰、是否返回主键、缓存、日志
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setLogImpl(Log4j2Impl.class);
        sqlSessionFactoryBean.setConfiguration(configuration);
        //==========配置Mybatis需要调用的拦截器类(分页插件)
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{
                initPageInterceptor()
        });
        return sqlSessionFactoryBean;
    }

    /**
     * 创建分页插件类对象
     * @Description 分页插件
     */
    @Bean
    public PageInterceptor initPageInterceptor(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        // 为分页拦截器准备配置参数
        Properties properties = new Properties();
        // 配置数据库方言
        properties.setProperty("helperDialect", "mysql");
        //该参数默认为false
        //设置为true时，就可以使用当前页页码+每页显示条数进行分页查询了
        properties.setProperty("offsetAsPageNum", "true");
        //分页查询时需要查询出满足条件的数据的总数量
        properties.setProperty("rowBoundsWithCount", "true");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }

}
